Optimize export lookup and simple activation - #772
Open
Andrew Arnott (AArnott) wants to merge 4 commits into
Open
Optimize export lookup and simple activation#772Andrew Arnott (AArnott) wants to merge 4 commits into
Andrew Arnott (AArnott) wants to merge 4 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document the activation performance investigation and retain only the non-expression optimizations on the active PR branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Andrew Arnott (AArnott)
marked this pull request as ready for review
August 28, 2026 01:11
There was a problem hiding this comment.
Pull request overview
This PR focuses on improving MEF runtime activation throughput by adding optimized fast paths for common export retrieval and simple non-shared activation, while also adding benchmarks and documentation to track and evaluate the performance work.
Changes:
- Add an optimized
GetExportedValue<T>()fast path viaExportProvider.TryGetExportedValue, and implement a runtime-provider cache for exact export lookups. - Add a narrow lifecycle bypass for simple non-shared parts (no imports / no
OnImportsSatisfied) and remove LINQ/extra allocations in constructor argument resolution. - Add BenchmarkDotNet activation benchmarks and a
PERFORMANCE.mdwrite-up describing the investigation and future directions.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| test/Microsoft.VisualStudio.Composition.Benchmarks/ActivationBenchmarks.cs | Adds steady-state activation benchmarks for several representative activation shapes (shared, transient, complex graphs, property imports, ImportMany). |
| src/Microsoft.VisualStudio.Composition/RuntimeExportProviderFactory+RuntimeExportProvider.cs | Implements a cached exact-export lookup fast path and reduces allocations in constructor argument resolution; adds simple non-shared lifecycle shortcut criteria. |
| src/Microsoft.VisualStudio.Composition/ExportProvider.cs | Introduces provider-specific TryGetExportedValue hook and a non-shared direct-initialization bypass in PartLifecycleTracker. |
| PERFORMANCE.md | Documents benchmark coverage, implemented optimizations, and future activation/JIT tradeoff ideas. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Avoid caching reentrant shared values before lifecycle finalization and make the performance documentation branch-independent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OnImportsSatisfiedcallbacksImportManyactivationPERFORMANCE.mdThis branch does not add expression-compiled constructors, setters, or activation plans. That experiment is preserved separately on
perf/compiled-activation-plansand has no pull request.Performance
Matched three-run medians from the IocPerformance scenarios. In the 1-thread variant, one thread performs 500,000 iterations. In the 2-thread variant, two threads share the same export provider and each performs 250,000 iterations concurrently. Each iteration resolves three exports, so both variants perform 1.5 million total resolutions. Values are total wall-clock time; the 2-thread variant measures concurrent throughput and contention rather than individual activation latency.
mainwas measured at26831df5; the PR column contains only the reduced, non-expression-compilation changes. The MEF2 control measurements differed by no more than 2.5% between runs.The largest gains come from cached shared retrieval and the narrow lifecycle bypass for simple non-shared parts. Imported graphs retain 1.4-3.0x improvements from cached root lookup and lower constructor-argument overhead. Expression-compiled constructors, setters, and graph activation are not included in these PR results.
Validation
Microsoft.VisualStudio.Composition.Tests: 2,064 net8.0 and 2,107 net472 tests passedValidation pipeline
vs-mef validation build 15110883